package com.polaris.live.ui.party.fragment.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.viewbinding.ViewBinding
import com.blankj.utilcode.util.KeyboardUtils
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.constant.PagConst
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.network.requestLoading
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.constant.UserConst
import com.polaris.live.databinding.PartyLiveLoadingBinding
import com.polaris.live.dialog.MinimizeDialog
import com.polaris.live.net.userService
import com.polaris.live.popup.party.PartyHangUpDialog
import com.polaris.live.resp.back_resp.DisplayUserBean
import com.polaris.live.resp.go_resp.SettingModifyBean
import com.polaris.live.translation.R
import com.polaris.live.ui.live.bean.LiveInitInfo
import com.polaris.live.ui.live.widget.PartyEditView
import com.polaris.live.ui.live.widget.listener.OnPartyBackPressedListener
import com.polaris.live.ui.live.widget.listener.OnPartySeatListener
import com.polaris.live.ui.party.listener.OnSpectatorFragmentListener
import com.polaris.live.ui.party.listener.PartyImListener
import com.polaris.live.ui.party.utils.LiveTipsType
import com.polaris.live.ui.party.utils.TipsShowType
import com.polaris.live.utils.CommonUtils.toBoolean
import com.polaris.live.utils.OtherPermissionUtils
import com.polaris.live.utils.XPopupUtils

/**
 * 派对观众基类
 * @author Created by 天晴 on 2024/3/21 9:51
 * @since 1.0.0
 **/
abstract class BasePartySpectatorFragment<VM : BaseViewModel, VB : ViewBinding> : BasePartyGestureFragment<VM, VB>(),
    PartyImListener,
    OnPartyBackPressedListener,
    OnPartySeatListener {

    var roomClose = false //房间是否被关闭，只有玩游戏的用户能使用到

    var mAnchorId: Long = -1
    var mEditView: PartyEditView? = null

    var isJoinRoom: Boolean = false

    var password: String? = null //房间密码

    private var mIsShowLoading = false // 是否在展示Loading
    private var mPartyHangUpDialog: PartyHangUpDialog? = null
    private var mOnClickGoOtherRoom: (() -> Unit)? = null

    private lateinit var mPdBinding: PartyLiveLoadingBinding
    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)
        if (view is ConstraintLayout) {
            mPdBinding =
                PartyLiveLoadingBinding.inflate(LayoutInflater.from(context), null, false)
            val pl = ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.MATCH_PARENT,
                ConstraintLayout.LayoutParams.MATCH_PARENT
            )
            (view as ConstraintLayout).addView(mPdBinding.root, pl)
        }
        mPdBinding.apply {
            pagView.apply {
                path = PagConst.LIVE_LOADING_PAG
                setRepeatCount(-1)
            }
            tipsBtn.setOnSingleClickListener {
                mOnClickGoOtherRoom?.invoke()
            }
            passwordView.setListener({
                KeyboardUtils.hideSoftInput(ViewUtils.requireWindow(requireContext()))
                dismissPassword()
                mOnSpectatorFragmentListener?.enterRoomPassword(it)
            }, {
                KeyboardUtils.hideSoftInput(ViewUtils.requireWindow(requireContext()))
                dismissPassword()
                mOnSpectatorFragmentListener?.closeActivity()
            })
        }

    }

    /**
     * 保存输入框
     */
    fun setEditView(editView: PartyEditView) {
        mEditView = editView
    }

    open fun initLiveInfo(data: LiveInitInfo, password: String?) {
        this.password = password
        isJoinRoom = true
        reset()
    }

    open fun exitRoom() {
        isJoinRoom = false
        reset()
    }

    /**
     * 房间已经关闭
     */
    fun roomClose(close: Boolean) {
        roomClose = close
        isJoinRoom = false
    }

    /**
     * 将提示重置
     */
    private fun reset() {
        unloading()
        goneTips()
        dismissPassword()
    }

    private fun goneTips() {
        mPdBinding.llTips.visibility = View.GONE
        mPdBinding.tvTips.visibility = View.GONE
        mPdBinding.tipsBtn.visibility = View.GONE
        mPdBinding.tvTips.text = ""
    }

    private fun showOneTips(tips: String) {
        mPdBinding.llTips.visibility = View.VISIBLE
        mPdBinding.tvTips.visibility = View.VISIBLE
        mPdBinding.tipsBtn.visibility = View.GONE
        mPdBinding.tvTips.text = tips
    }

    private fun showOneTipsAndBtn(tips: String, goOtherRoom: (() -> Unit)? = null) {
        mOnClickGoOtherRoom = goOtherRoom
        mPdBinding.llTips.visibility = View.VISIBLE
        mPdBinding.tvTips.visibility = View.VISIBLE
        mPdBinding.tipsBtn.visibility = View.VISIBLE
        mPdBinding.tvTips.text = tips
    }

    /**
     * 显示直播间信息
     */
    fun loading() {
        withLoaded {
            if (!mIsShowLoading && !isJoinRoom) {
                mIsShowLoading = true
                mPdBinding.llLoading.visibility = View.VISIBLE
                mPdBinding.pagView.play()
            }
        }
    }

    fun unloading() {
        withLoaded {
            if (mIsShowLoading) {
                mIsShowLoading = false
                mPdBinding.llLoading.visibility = View.GONE
                mPdBinding.pagView.pause()
            }
        }
    }

    /**
     * 显示直播间信息异常
     */
    fun tipsShowType(@LiveTipsType type: Int, tips: String, goOtherRoom: (() -> Unit)? = null) {
        withLoaded {
            unloading()
            when (type) {
                TipsShowType.ERROR_LIVE_TIPS -> {
                    showOneTips(tips)
                }

                TipsShowType.ERROR_LIVE_CLOSE -> {
                    showOneTips(tips)
                }

                TipsShowType.ERROR_LIVE_OTHER -> {
                    showOneTipsAndBtn(tips, goOtherRoom)
                }
            }

        }
    }

    fun showPassword(passwordError: Boolean) {
        withLoaded {
            mEditView?.setKeyboardListerState(false)
            mPdBinding.passwordView.visibility = View.VISIBLE
            mPdBinding.passwordView.setUi(passwordError)
        }

    }

    private fun dismissPassword() {
        withLoaded {
            mEditView?.setKeyboardListerState(true)
            mPdBinding.passwordView.onDismiss()
            mPdBinding.passwordView.visibility = View.GONE
        }
    }

    /**
     * 显示礼物轮盘
     */
    abstract fun showGiftDialog()

    /**
     * 判断id是否相同，不同就切换直播间
     */
    abstract fun switchUserRoom(anchorId: Long? = null, childRouter: String? = null)

    abstract fun nextData(displayUserBean: DisplayUserBean)
    abstract fun onMinimize()

    /**
     * 房间类型
     *  //0 语音房   1游戏房  2视频房
     */
    abstract fun roomType(): Int


    /**
     * activirty设置的监听
     */

    var mOnSpectatorFragmentListener: OnSpectatorFragmentListener? = null
    fun setOnSpectatorFragmentListener(mOnSpectatorFragmentListener: OnSpectatorFragmentListener) {
        this.mOnSpectatorFragmentListener = mOnSpectatorFragmentListener
    }

    override fun onBackPressed(): Boolean {
        if (!isCreated() || activity?.isFinishing != false) {
            return true
        }
        if (roomClose) {
            return false
        }

        if (getIsGameMode()) {
            ToastGravity.showGravity(R.string.exit_party_paly_game_tips)
            return true
        }
        if (roomType() == PARTY_VOICE_ROOM) { //现在只有语言房开启
            val minimizeExitRoom = UserManager.getUser().setting?.minimizeExitRoom.toBoolean()
            if (minimizeExitRoom) { //设置开启了最小化
                OtherPermissionUtils.checkAndRequestOverlayPermission(requireContext()) {
                    if (it) {
                        onMinimize()
                    } else {
                        mOnSpectatorFragmentListener?.closeActivity(null)
                    }
                }
                return true
            }
        }
        return if (getIsRoomSeat()) {
            if (mPartyHangUpDialog == null) {
                mPartyHangUpDialog =
                    PartyHangUpDialog(requireContext()) {
                        mOnSpectatorFragmentListener?.closeActivity(null)
                    }
            }
            mPartyHangUpDialog?.also { XPopupUtils.showViewPopup(it, isDisposable = false) }
            true
        } else {
            if (roomType() == PARTY_VOICE_ROOM) { //现在只有语言房开启
                val pd = CacheUtil.getFloatingViewTipsFromKV()
                if (!pd) { //自己不在座位且没有提示过最小化新功能
                    CacheUtil.saveFloatingViewTips(true)
                    MinimizeDialog.show(requireContext(), {
                        OtherPermissionUtils.checkAndRequestOverlayPermission(requireContext(), false) {
                            if (it) {
                                settingModify(UserConst.UserSetting.MINIMIZE, AppConst.YES)
                                onMinimize()
                            }
                        }
                    }, {
                        mOnSpectatorFragmentListener?.closeActivity(null)
                    })
                    true
                } else {
                    false
                }
            } else {
                false
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mEditView = null
        mOnSpectatorFragmentListener = null
    }

    /**
     * 修改用户设置
     */
    private fun settingModify(@UserConst.SettingType type: Int, state: Int) {
        mViewModel.requestLoading({ userService.settingModify(SettingModifyBean(type, state)) }, {
            when (type) {
                UserConst.UserSetting.MINIMIZE -> {
                    UserManager.getUser().setting?.minimizeExitRoom = state
                }
            }
        }, {
            ToastGravity.showGravity(it.errorMsg)
        })
    }

    companion object {
        const val PARTY_VOICE_ROOM = 0  //语音房
        const val PARTY_GAME_ROOM = 1   //游戏房
        const val PARTY_VIDEO_ROOM = 2  //视频房

    }
}